/*
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.nio.charset.Charset;

/**
 * See {@link wtkx.Component} writer.  Synchronous output binding
 * permits authentication.
 * 
 * @author jdp
 */
public class UrlcOutputStream
    extends java.io.FilterOutputStream
{
    public final static Charset UTF8 = Charset.forName("UTF-8");


    protected final Object connection;

    protected final URLConnection urlc;

    protected boolean committed;

    protected UrlcInputStream input;

    protected int status;

    protected String message;

    protected Writer writer;


    public UrlcOutputStream(URLConnection c)
        throws java.io.IOException
    {
        super(c.getOutputStream());
        this.connection = c;
        this.urlc = c;
    }
    public UrlcOutputStream(URLConnection c, File f)
        throws java.io.IOException
    {
        super(new FileOutputStream(f));
        this.connection = f;
        this.urlc = c;
    }


    public Writer getWriter(){
        Writer writer = this.writer;
        if (null == writer){
            writer = new OutputStreamWriter(this,UTF8);
            this.writer = writer;
        }
        return writer;
    }
    public boolean isHttp(){
        return (this.connection instanceof HttpURLConnection);
    }
    public boolean isFile(){
        return (this.connection instanceof File);
    }
    public boolean isURL(){
        return (this.connection instanceof URLConnection);
    }
    public boolean isCommitted(){
        return this.committed;
    }
    public boolean hasStatus(){
        return (0 < this.status);
    }
    public int getStatus(){
        return this.status;
    }
    public boolean isOk(){
        switch (this.status){
        case 0:
        case 200:
            return true;
        default:
            return false;
        }
    }
    public boolean isNotOk(){
        return (!this.isOk());
    }
    public String getStatusMessage(){
        return this.message;
    }
    public String getResponse(){
        if (0 == this.status)
            return "";
        else
            return (String.valueOf(this.status)+' '+this.message);
    }
    public URLConnection getConnection(){
        return this.urlc;
    }
    public HttpURLConnection getHttp(){
        return (HttpURLConnection)this.connection;
    }
    public File getFile(){
        return (File)this.connection;
    }
    public UrlcInputStream getInputStream()
        throws java.io.IOException
    {
        UrlcInputStream input = this.input;
        if (null == input){
            input = new UrlcInputStream(this.urlc);
            this.input = input;
        }
        return input;
    }
    public void close()
        throws java.io.IOException
    {
        if (this.committed)
            return ;
        else {
            try {
                super.flush();
                if (this.connection instanceof HttpURLConnection){
                    HttpURLConnection http = (HttpURLConnection)this.connection;
                    synchronized(this){
                        this.committed = true;
                        this.status = http.getResponseCode();
                        this.message = http.getResponseMessage();
                    }
                }
            }
            finally {
                try {
                    super.close();
                }
                finally {
                    if (this.connection instanceof HttpURLConnection)
                        ((HttpURLConnection)this.connection).disconnect();
                }
            }
        }
    }
}
